﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace Mimoza.PuttyPlugin
{
    class ExecutePlugin : Mimoza.PluginLayer.IExecutePlugin
    {
        const string c_pluginFileExt = "lnk";

        public ExecutePlugin()
        {
            m_pluginFileSync = new RdpPlugin.PluginFileSync(c_pluginFileExt);
            m_pluginFileSync.HasPolicyIdInPlainString = true;

            PluginFileSync.Do(PuttyFilesFolder);

            SyncStartupFiles();
        }

        public RdpPlugin.PluginFileSync PluginFileSync
        {
            get { return m_pluginFileSync; }
        }

        #region IExecutePlugin Members

        public string PluginId
        {
            get { return this.ToString(); }
        }

        public void Add(Mimoza.ObjectLayer.Policy policy)
        {
            Add(policy, GetData(policy.Data));
            //RegistrySettings sett = new RegistrySettings(@"SOFTWARE\Microsoft\WBT\Clients\Registration\PuTTy\Connections\put_test");
            //sett.SaveToFile("c:/f.tmp");
        }

        public void Remove(Mimoza.ObjectLayer.Policy policy)
        {
            Remove(policy, GetData(policy.Data));
        }

        public void Update(Mimoza.ObjectLayer.Policy policy)
        {
            Update(policy, GetData(policy.Data));
        }

        #endregion

        void Add(Mimoza.ObjectLayer.Policy policy, PuttyData data)
        {
            Trace("Mimoza.PuttyPlugin.ExecutePlugin.Add Name - '" + policy.Name + 
                            "' Computer - '" + data.Computer +
                            "' User - '" + data.UserName + "'.");

            string puttyFileName = BuildPuttyFileName(policy, data);

            PuttyFile puttyFile = new PuttyFile();
            string binaryStr = puttyFile.GetText(data, policy.ID);

            RegistrySettings sett = new RegistrySettings();
            sett.ApplyFromBinary(binaryStr);

            puttyFile.CreateShortcutFile(puttyFileName, data, policy.ID);

            PluginFileSync.Replace(puttyFileName);

            if (data.IsStartOnStartup) SyncStartupFiles();
        }

        void Remove(Mimoza.ObjectLayer.Policy policy, PuttyData data)
        {
            Trace("Mimoza.PuttyPlugin.ExecutePlugin.Remove Name - '" + policy.Name +
                            "' Computer - '" + data.Computer +
                            "' User - '" + data.UserName + "'.");

            PuttyFile puttyFile = new PuttyFile();
            string binaryStr = puttyFile.GetText(data, policy.ID);

            RegistrySettings sett = new RegistrySettings();
            sett.EraseFrom(binaryStr);

            RemovePuttyFileByName(policy, data);

            if (data.IsStartOnStartup) SyncStartupFiles();
        }

        void Update(Mimoza.ObjectLayer.Policy policy, PuttyData data)
        {
            Trace("Mimoza.PuttyPlugin.ExecutePlugin.Update Name - '" + policy.Name +
                            "' Computer - '" + data.Computer +
                            "' User - '" + data.UserName + "'.");

            Remove(policy, data);
            Add(policy, data);
        }

        private static void SyncStartupFiles()
        {
            RdpPlugin.PluginFileSync pluginFileSync = new RdpPlugin.PluginFileSync(Common.GlobalSettings.StartupPath, c_pluginFileExt);
            pluginFileSync.HasPolicyIdInPlainString = true;
            pluginFileSync.Do(PuttyFilesFolder, true);
        }

        private static string BuildPuttyFileName(Mimoza.ObjectLayer.Policy policy, PuttyData data)
        {
            string filePath = PuttyFilesFolder;
            string fileName = Path.Combine(filePath, data.SessionName + "." + policy.ID.ToString());

            return fileName;
        }

        private static string PuttyFilesFolder
        {
            get
            {
                return Path.Combine(Common.GlobalSettings.DataPath, "putty");
            }
        }

        private void RemovePuttyFileByName(Mimoza.ObjectLayer.Policy policy, PuttyData data)
        {
            string[] puttyFiles = Directory.GetFiles(PuttyFilesFolder, "*." + policy.ID.ToString());
            string puttyFileName = (puttyFiles != null && puttyFiles.Length > 0) ? puttyFiles[0] : "";

            if (!string.IsNullOrEmpty(puttyFileName) && System.IO.File.Exists(puttyFileName))
            {
                Common.Logger.Log.Info("Mimoza.PuttyPlugin.ExecutePlugin: delete Putty file name - '" +
                    puttyFileName + "'.");

                System.IO.File.Delete(puttyFileName);

                PluginFileSync.Remove(puttyFileName);
            }
        }

        void Trace(string outStr)
        {
            Common.Logger.Log.Trace(outStr);
            //System.Windows.Forms.MessageBox.Show(outStr);
        }

        PuttyData GetData(string data)
        {
            return PuttyData.Deserialize(data);
        }

        RdpPlugin.PluginFileSync m_pluginFileSync;
    }
}
